#include <iostream>
using namespace std;

// template 告诉编译器 我要开始声明虚拟类型了
// typename 是声明虚拟类型的关键字 
// T        就是我们声明的虚拟类型 可用于下面函数的返回值、形参、定义变量
// <> 里面的内容 称为 类型形参表
// 如果需要多个虚拟类型 可以使用 逗号分隔 写多个 如下
// template <typename T1, typename T2, ... typename Tn>
// 虚拟类型的生效范围：只对下面一个函数生效 如果后面再有函数 需要重新声明虚拟类型
template <typename T>
T my_max(T x, T y){
    return x > y ? x : y;
}

// 如果后面再有函数 需要重新声明虚拟类型
template <typename T>
T my_min(T x, T y){
    return x < y ? x : y;
}

int main(int argc, const char *argv[]){
    // 模板函数的调用
    // 也可以按正常调用函数的方式
    // 编译器会根据实参的类型 自动推导 本地调用需要给类型传什么参数
    cout << my_max(10, 20) << endl; // 20
    cout << my_max('Z', 'A') << endl; // Z
    cout << my_max(10.2, 12.3) << endl; // 12.3

    cout << "----------------" << endl;

    // 也可以使用 给类型传参 的方式调用模板函数
    // 关于传参 遵循规则：尖找尖 圆找圆
    // 模板函数调用时 <> 里面的内容 称为 类型实参表
    // 相当于明确告诉编译器 本地调用模板函数 给类型传的是 int 
    cout << my_min<int>(10, 20) << endl; // 10


    // 相当于明确告诉编译器 本地调用模板函数 给类型传的是 char
    cout << my_min<char>('Z', 'A') << endl; // A
    // 相当于明确告诉编译器 本地调用模板函数 给类型传的是 double
    cout << my_min<double>(10.2, 12.3) << endl; // 10.2

    return 0;
}